package org.flckphoto;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import org.flckphoto.PhotoManager;

/**
 * Singleton activity class that launches camera functionality
 */
public class CameraManager extends Activity{
	private static final String TAG = "CameraManager";
	private Preview cameraPreview;
	private Button takePictureButton;
	public byte[] tempData;//junit testing
	private static CameraManager singleton;
	private static final int PHOTOMANAGER_REQUEST = 99;
	
	/**
	 * Singleton Function for other classes to use
	 */
	public static CameraManager getSingleton(){
		if(singleton == null){
			Log.d(TAG, "Instantiating CameraManager singleton instance");
		singleton = new CameraManager();}
		return singleton;
	}
	
	/**
	 * Called when the activity is first created
	 * 
	 * @param savedInstanceState A mapping from String values to various Parcelable types. 

	 */
	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.camera_ui);
		
		//Sets up the layout of the preview on screen
		cameraPreview = new Preview(this);
		((FrameLayout) findViewById(R.id.preview)).addView(cameraPreview);
		
		//Sets up the take picture button and setup the button listener
		takePictureButton = (Button) findViewById(R.id.takePictureButton);
		takePictureButton.setOnClickListener(new OnClickListener(){
			public void onClick(View v){
				takePictureButton.setEnabled(false);
				cameraPreview.camera.takePicture(shutterCallback, null, jpegCallback);
			}
		});
		Log.d(TAG, "onCreate finished");
	}
	
	/**
	 * Shutter Callback for the moment a picture is taken
	 */
	 ShutterCallback shutterCallback = new ShutterCallback(){
		 public void onShutter(){
			 Log.d(TAG, "onShutter called");
		 }
	 };
	 
	 @Override
	 public void onPause(){
		 super.onPause();
		 if(cameraPreview != null && cameraPreview.camera != null)
			 cameraPreview.camera.stopPreview();
		 
		 
	 }
	 
	 @Override
	 public void onResume(){
		 super.onResume();
		 if(cameraPreview != null && cameraPreview.camera != null)
			 cameraPreview.camera.startPreview();
		 
		 if(!takePictureButton.isEnabled())
			 takePictureButton.setEnabled(true);
		 
	 }
	 
	 
	 /**
	  * Retrieving the jpeg picture from the camera and compress it to send 
	  * to PhotoManager
	  */
	 PictureCallback jpegCallback = new PictureCallback(){

		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			Log.d(TAG, "onPictureTaken");
			
			//Compresses the image to be able to send it
			BitmapFactory.Options ops = new BitmapFactory.Options();
			ops.inSampleSize = 2;
			Bitmap tempImage = BitmapFactory.decodeByteArray(data, 0, data.length, ops);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			tempImage.compress(CompressFormat.JPEG, 80, out);
			tempData = out.toByteArray();
			
			try {
				out.close();
				tempImage.recycle();
			}
			catch(IOException e) {
				Log.e(TAG, e.getMessage());
			}
			
			
			//Stores the image in the imageData variable
			if(tempData!= null){
				Log.d(TAG, "Image Data assigned to imageData variable");
				Intent intent = new Intent(getApplicationContext(), PhotoManager.class);
				intent.putExtra("image", tempData);
				intent.putExtra("path", "");
				intent.putExtra("saved", false);
				startActivityForResult(intent, PHOTOMANAGER_REQUEST);
			
			}
			
			else{
				Log.e(TAG, "Image was nulll");
			}
			
		}
		 
	 };
	 


	 /**
	  * Gets result of PhotoManager when it has finished
	  * 
	  * @param requestCode the type of code requested from the activity
	  * @param resultCode the type of code recieved from the activity
	  */
	 @Override
	 public void onActivityResult(int requestCode, int resultCode, 
			 						Intent data) {
		 if(requestCode == PHOTOMANAGER_REQUEST) {
			 if(resultCode == Activity.RESULT_OK) {
				 Log.d(TAG, "PhotoManager finished");
				 //cameraPreview.camera.startPreview();
				 
				 setContentView(R.layout.camera_ui);
					
					//Sets up the layout of the preview on screen
					cameraPreview = new Preview(this);
					((FrameLayout) findViewById(R.id.preview)).addView(cameraPreview);
					
					//Sets up the take picture button and setup the button listener
					takePictureButton = (Button) findViewById(R.id.takePictureButton);
					takePictureButton.setOnClickListener(new OnClickListener(){
						public void onClick(View v){
							takePictureButton.setEnabled(false);
							cameraPreview.camera.takePicture(shutterCallback, null, jpegCallback);
						}
					});
			 }
			 else if(resultCode == Activity.RESULT_CANCELED) {
				 Log.e(TAG, "Bad result from PhotoManager");
			 }
		 }
	 }
	 
}
